﻿using KinonekoSoftware.CodariaDB.Documents.Theories;
using KinonekoSoftware.CodariaDB.Documents.Theories.Rarities;
using KinonekoSoftware.CodariaDB.Runtimes.Initializers;
using KinonekoSoftware.Studio.Models.Theories;

namespace KinonekoSoftware.Studio.Pages.Theories.Rarities
{
    public class RarityEditorViewModel : RepositoryGalleryItem
    {
        private readonly IRepository    _repository;
        private readonly TheoryEngine_Rarity _theory;
        private readonly RarityComparer _comparer;

        public RarityEditorViewModel()
        {
            _repository = Platform.GetRepository();
            _theory     = Platform.GetEngine<TheoryEngine_Rarity>();
            _comparer   = new RarityComparer();

            Rarities       = new ObservableCollection<TheoryOfRarityPresenter>();
            SortedRarities = new ObservableCollection<TheoryOfRarityPresenter>();

            NewRarityCommand       = CreateCommand(DoNewRarityCommand);
            OpenNotionCommand      = CreateCommand<TheoryOfRarityPresenter>(DoOpenNotionCommand);
            OpenStoryCommand       = CreateCommand<TheoryOfRarityPresenter>(DoOpenStoryCommand);
            EditRarityCommand      = CreateCommand<TheoryOfRarityPresenter>(DoEditRarityCommand);
            EditTemplatedCommand   = CreateCommand<TheoryOfRarityPresenter>(DoEditTemplatedRarityCommand);
            RemoveRarityCommand    = CreateCommand<TheoryOfRarityPresenter>(DoRemoveRarityCommand);


            Rarities.AddMany(_theory.Collection.Select(TheoryOfRarityPresenter.Select));
            SortedRarities.AddMany(Rarities.OrderDescending(_comparer), true);
        }

        private void Save()
        {
            Xplat.Debug($"正在保存TheoryOfRarity属性，Version:{_theory.Version}");
        }



        //-------------------------------------------------
        //
        //          Command Handlers
        //
        //-------------------------------------------------

        private async void DoNewRarityCommand()
        {
            var r = await NewRarityViewModel.Create();

            if (!r.IsFinished)
            {
                return;
            }

            var val = r.Value;

            //
            //
            _theory.Add(val);

            //
            //
            Rarities.Add(TheoryOfRarityPresenter.Select(val));

            //
            //
            Save();
        }

        private void DoEditTemplatedRarityCommand(TheoryOfRarityPresenter element)
        {
            if (element is null)
            {
                return;
            }

            var context = new PageContext
            {
                Id = element.Id,
            };
            context.Set(ContextBase.Key_Value, element);
            Core.GoTo<TemplatedElementEditorViewModel>(context);

            //
            //
            Save();
        }

        private async void DoEditRarityCommand(TheoryOfRarityPresenter element)
        {
            if (element is null)
            {
                return;
            }

            var r = await NewRarityViewModel.Edit(element.TargetObject);

            if (!r.IsFinished)
            {
                return;
            }

            //
            //
            Save();

            //
            //
            element.RaiseUpdates();
        }


        private async void DoRemoveRarityCommand(TheoryOfRarityPresenter element)
        {
            if (element is null)
            {
                return;
            }

            if (!await RemoveItem())
            {
                return;
            }

            Rarities.Remove(element);
            _theory.Remove(element.TargetObject);

            Save();
        }

        private void DoOpenNotionCommand(TheoryOfRarityPresenter element)
        {
            this.ThisNotion(element.TargetObject);
        }


        private void DoOpenStoryCommand(TheoryOfRarityPresenter element)
        {
            this.ThisStory(element.TargetObject);
        }


        public string TheoryName
        {
            get => _theory.CalledName;
            set
            {
                _theory.CalledName = value;
                RaiseUpdated();
                Save();
            }
        }


        public string CalledName
        {
            get => _theory.CalledName;
            set
            {
                _theory.CalledName = value;
                RaiseUpdated();
                Save();
            }
        }


        public ICommandEX NewRarityCommand       { get; }
        public ICommandEX EditRarityCommand      { get; }
        public ICommandEX EditTemplatedCommand   { get; }
        public ICommandEX RemoveRarityCommand    { get; }
        public ICommandEX OpenNotionCommand      { get; }
        public ICommandEX OpenStoryCommand       { get; }

        public ObservableCollection<TheoryOfRarityPresenter> Rarities       { get; }
        public ObservableCollection<TheoryOfRarityPresenter> SortedRarities { get; }
    }
}